﻿#include"XQFtp.hpp"
#include"curl/curl.h"
#include"XStringOperation.hpp"
#include"QCoding.h"
#include<QDebug>
//回调函数，获取返回的信息
static qint64 parse_dir_listing(void* ptr, qint64 size, qint64 nmemb, void* userdata) {
    QString& fileInfo= *(QString*)userdata;
    char* line = (char*)ptr;
    fileInfo += QCoding::GbkToUtf8(QByteArray(line));
    //if (strstr(line, "..") || strstr(line, ".")) {
    //    return size * nmemb; // Skip parent and current directory
    //    // 跳过上级和当前目录
    //}

    //if (line[0] == 'd') {
    //    // Skip directory entries
    //    // 跳过目录项
    //    return size * nmemb;
    //}
   
    return size * nmemb;
}
QList<XQFtrFileInfo> XQFtp::fileList(const QString& path, const bool updataPath)
{
    curl_global_init(CURL_GLOBAL_DEFAULT);
    auto curl=init();
    QList<XQFtrFileInfo> file_list;//列表
    QString fileInfo;
    //设置url
    QString url = setUrl(path, updataPath);
    if (url.back() != '/')//尾部补斜杠
        url += '/';
    curl_easy_setopt(curl, CURLOPT_URL, url.toLocal8Bit().data());
    // 设置 FTP 目录列表命令
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "LIST");
    // 设置回调函数和回调数据
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, parse_dir_listing);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fileInfo);

    // 执行请求
    auto res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s ", curl_easy_strerror(res));
        // 请求失败
    }
    curl_easy_cleanup(curl);
    curl_global_cleanup();
    //处理数据
    auto infolist = XStringOperation::strtok(fileInfo, "\r\n");
    for (auto& info : infolist)
    {
        file_list.append(info);
    }
    emit fileListFinish(file_list);//将结果通过信号返回
    return std::move(file_list);
}
//处理查询文件大小，服务器发送返回的信息中提取大小
static size_t acceptFileSize(char* ptr, size_t size, size_t nmemb, void* userdata)
{
    // 计算接收到的数据长度
    size_t total_size = size * nmemb;
    // 将数据复制到用户缓冲区中
    size_t* fileSize = (size_t*)userdata;
    const char* head = "Content-Length:";
    QString text = QString(ptr);
    int nSel = text.indexOf(head);
    if (nSel != -1)
    {
        *fileSize = text.mid(nSel+strlen(head)).toULongLong();
    }
    // 返回已处理的数据长度
    return total_size;
}
size_t XQFtp::fileSize(const QString& remote_file_path)
{
    CURL* curl = init();
    CURLcode res;
    size_t  file_size =0;
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, setUrl(remote_file_path).toLocal8Bit().data());
        curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // 发送HEAD请求
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L); // 禁用调试输出
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, acceptFileSize);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file_size);
        res = curl_easy_perform(curl);
    }
    return file_size;
}

void XQFtp::copy(const QString& source, const QString& newPath)
{
    CURL* curl=init();
    CURLcode res;
    if (curl) {
        // 配置来源和目的地 URL
          //设置url
        QString sourceUrl = setUrl(source);
        QString newUrl = setUrl(newPath);
        curl_easy_setopt(curl, CURLOPT_URL, source.toLocal8Bit().data());
        curl_easy_setopt(curl, CURLOPT_UPLOAD, 0L);
        curl_easy_setopt(curl, CURLOPT_URL, newPath.toLocal8Bit().data());


        // 执行 CURL 请求
        res = curl_easy_perform(curl);

        // 检查 CURL 请求是否成功
        if (res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));

        // 清理 CURL
        curl_easy_cleanup(curl);
    }
}
